package com.dcloud.core.dsplugin.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dcloud.core.client.IClient;
import com.dcloud.core.dsplugin.IDsService;
import com.dcloud.core.source.RdbmsSource;
import com.dcloud.dbdrive.IClientFactory;
import com.dcloud.manage.service.ICollectSourceDefineService;
import com.dcloud.manage.service.ICollectSourceService;
import com.dcloud.manage.service.entity.CollectSource;
import com.dcloud.manage.service.entity.CollectSourceDefine;
import com.dcloud.manage.service.entity.DBInfoEntity;
import com.dcloud.manage.service.entity.DBParamsEntity;
import com.dcloud.utils.ClassUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.groupingBy;

@Service
public class IDsServiceImpl implements IDsService {

    @Autowired
    ICollectSourceService iSourceService  ;

    @Autowired
    ICollectSourceDefineService iCollectSourceDefineService ;

    @Autowired
    IClientFactory iClientFactory;


    /**
     * @Author shijf
     * @Description 根据数据源id,测试连接
     * @Date 15:15 2023/5/24
     * @param id 数据源id
     * @return com.dcloud.manage.vo.SourceTestConnVO
     **/
    @Override
    public Result testConn(Integer id) throws ClassNotFoundException, InstantiationException, IllegalAccessException {


        //查询数据源配置信息
        DBInfoEntity dbInfoEntity = iSourceService.queryDbInfoBySourceTid(id);

        Map<String, List<DBParamsEntity>> collect = dbInfoEntity.getList().stream().collect(groupingBy(DBParamsEntity::getParamCode));
        //反射构建source类,将数据表参数值根据反射set 插入到对象中
        Class<?> aClass = Class.forName(dbInfoEntity.getClassLoad());
        RdbmsSource defineSource = (RdbmsSource) aClass.newInstance();

        Field[] allFields = ClassUtils.getAllFields(aClass);
        for(Field field : allFields){
            if(collect.containsKey(field.getName())){
                String paramValue = collect.get(field.getName()).get(0).getParamValue();
                field.setAccessible(true);
                field.set(defineSource,paramValue);
            }
        }

        //获取客户端
        IClient client = iClientFactory.getDbdriveByCode(dbInfoEntity.getSourceCode());
        try {
            //调用客户端测试连接的接口
            Boolean aBoolean = client.testCon(defineSource);
            return Result.OK("连接成功");
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public List<Map<String, Object>> selectSqlBySourceId(String sql, Integer sourceId, Long limit) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //查询数据源配置信息
        DBInfoEntity dbInfoEntity = iSourceService.queryDbInfoBySourceTid(sourceId);

        Map<String, List<DBParamsEntity>> collect = dbInfoEntity.getList().stream().collect(groupingBy(DBParamsEntity::getParamCode));
        //反射构建source类,将数据表参数值根据反射set 插入到对象中
        Class<?> aClass = Class.forName(dbInfoEntity.getClassLoad());
        RdbmsSource defineSource = (RdbmsSource) aClass.newInstance();

        Field[] allFields = ClassUtils.getAllFields(aClass);
        for(Field field : allFields){
            if(collect.containsKey(field.getName())){
                String paramValue = collect.get(field.getName()).get(0).getParamValue();
                field.setAccessible(true);
                field.set(defineSource,paramValue);
            }
        }

        //获取客户端
        IClient client = iClientFactory.getDbdriveByCode(dbInfoEntity.getSourceCode());

        List list = client.execQueryWithLimit(defineSource, sql, null, limit);
        return list;
    }

    @Override
    public Result<?> getAllTableFromDs(Integer tid) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //查询数据源配置信息
        DBInfoEntity dbInfoEntity = iSourceService.queryDbInfoBySourceTid(tid);

        Map<String, List<DBParamsEntity>> collect = dbInfoEntity.getList().stream().collect(groupingBy(DBParamsEntity::getParamCode));
        //反射构建source类,将数据表参数值根据反射set 插入到对象中
        Class<?> aClass = Class.forName(dbInfoEntity.getClassLoad());
        RdbmsSource defineSource = (RdbmsSource) aClass.newInstance();

        Field[] allFields = ClassUtils.getAllFields(aClass);
        for(Field field : allFields){
            if(collect.containsKey(field.getName())){
                String paramValue = collect.get(field.getName()).get(0).getParamValue();
                field.setAccessible(true);
                field.set(defineSource,paramValue);
            }
        }

        //获取客户端
        IClient client = iClientFactory.getDbdriveByCode(dbInfoEntity.getSourceCode());
        try {
            //调用客户端测试连接的接口
            List<Map<String,Object>> list = client.getAllTable(defineSource);
            return Result.OK(list);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public Result<?> getAllSourceByType(String sourceCode) {
        //查询数据源定义的id
        CollectSourceDefine csd = iCollectSourceDefineService.selectBySourceCode(sourceCode);
        if(csd == null){
            throw new JeecgBootException("数据源类型不存在");
        }

        //根据数据定义查询数据列表信息
        List<CollectSource> collectSources = iSourceService.list(new QueryWrapper<CollectSource>()
                .eq("source_def_tid",csd.getTid()));
        return Result.OK(collectSources);
    }
}
